local desc_openheg_mode = [[
  # 明牌国战模式简介
  ___
    玩家以国为单位乱战
    非蜀魏吴群势力随机分配一个势力
    游戏开始时，所有小势力角色选择并获得一个武将技能并摸1张牌
  
    击杀奖励  :小势力击杀大势力摸三张牌，其余情况摸2张牌；击杀同势力失去区域内的牌
    击杀野心家额外恢复一点体力



]]

local H = require "packages/hegemony/util"

local openheg
--分配势力

local function getKingdomlist(room,k)
  local kingdomMapper = 1
  for _, p in ipairs( room.players) do
      local kingdom = p.role

    if  kingdom == k then
      kingdomMapper = kingdomMapper + 1
    end
  end
  return kingdomMapper
end


local function choosekindom(room,kingdom)
  local allKingdoms = {"wei", "shu", "wu", "qun"}
  local kingdom=kingdom
  if not table.contains(allKingdoms,kingdom) then
      kingdom=table.random(allKingdoms)
  end
  local list=getKingdomlist(room,kingdom)
    if list<=(#room.players)//2 then
      return kingdom
    else
      return "wild"
    end



end
--获得技能

local function huanhua_Newskill(room,players)
  local players =players
  local n = #players
  local ChosenGenerals = {}
  for _, p in ipairs(players) do
    table.insert(ChosenGenerals, p.general)
  end
  local generals = Fk:getGeneralsRandomly(8 * n, Fk:getAllGenerals(), ChosenGenerals)
  local skills = {}
  for _, g in ipairs(generals) do
    for _, s in ipairs(g.skills) do
      if not (s.lordSkill) then
        table.insertIfNeed(skills, s.name)
      end
    end
  end
  for _, p in ipairs(players) do
    local choices = {}
    for i = 1, math.min(3, #skills) do
      table.shuffle(skills)
      table.insert(choices, 1, table.remove(skills, 1))
    end
    p.request_data = json.encode({ choices, choices, "openheg_choice", "#openheg-choice:"..p.id, true })
  end

  room:notifyMoveFocus(players, "AskForChoice")
  room:doBroadcastRequest("AskForChoice", players)

  for _, p in ipairs(players) do
    local ChosenSkill
    if p.reply_ready then
      if p.client_reply ~= "DrawTwo"
        then ChosenSkill = p.client_reply
        room:handleAddLoseSkills(p, ChosenSkill, nil, false)
        p:drawCards(1)
      end
    end
  end
end







local openheg_getLogic = function()
  local openheg_logic = GameLogic:subclass("jbs__openheg_logic")

  function openheg_logic:assignRoles()
    local room = self.room
    for _, p in ipairs(room.players) do
      p.role_shown = false
      p.role = "hidden"
      room:broadcastProperty(p, "role")
    end
  
    -- for adjustSeats
    room.players[1].role = "lord"
  end
  
  function openheg_logic:chooseGenerals()
    local room = self.room
    local generalNum = room:getSettings('generalNum')
    local lord = room:getLord()
    room.current = lord
    lord.role = "hidden"

    local nonlord = room.players
    local generals = Fk:getGeneralsRandomly(#nonlord * generalNum)
    table.shuffle(generals)
    for _, p in ipairs(nonlord) do
      local arg = {}
      for i = 1, generalNum do
        table.insert(arg, table.remove(generals, 1).name)
      end
      p:setMark("@seat", "seat#" .. tostring(p.seat))
      p:doNotify("SetPlayerMark", json.encode{ p.id, "@seat", "seat#" .. tostring(p.seat)})
      p.request_data = json.encode({ arg, 1 })
      p.default_reply = arg[1]
    end

    room:doBroadcastRequest("AskForGeneral", nonlord)
    for _, p in ipairs(nonlord) do
      if p.general == "" and p.reply_ready then
        local general = json.decode(p.client_reply)[1]
        room:setPlayerGeneral(p, general, true, true)
      else
        room:setPlayerGeneral(p, p.default_reply, true, true)
      end
      p.default_reply = ""
    end

    room:askForChooseKingdom(nonlord)
  end

  function openheg_logic:broadcastGeneral()
    local room = self.room
    local players = room.players
  
    for _, p in ipairs(players) do
      p:setMark("@seat", 0)
      p:doNotify("SetPlayerMark", json.encode{ p.id, "@seat", 0})
      assert(p.general ~= "")
      local general = Fk.generals[p.general]
      local deputy = Fk.generals[p.deputyGeneral]
      p.maxHp = p:getGeneralMaxHp()
      p.hp = deputy and math.floor((deputy.hp + general.hp) / 2) or general.hp
      p.shield = math.min(general.shield + (deputy and deputy.shield or 0), 5)
      -- TODO: setup AI here
      p.role=choosekindom(room,p.kingdom)
      p.kingdom=p.role
      
      room:broadcastProperty(p, "general")
      room:broadcastProperty(p, "kingdom")
      room:broadcastProperty(p, "role")

      room:broadcastProperty(p, "deputyGeneral")
      room:broadcastProperty(p, "maxHp")
      room:broadcastProperty(p, "hp")
      room:broadcastProperty(p, "shield")
    end
  end
  return openheg_logic
end

local heg_invalid = fk.CreateInvaliditySkill{
  name = "#_heg_invalid",
  invalidity_func = function(self, player, skill)
  end,
}

local wildKingdoms = {"heg_qin", "heg_qi", "heg_chu", "heg_yan", "heg_zhao", "heg_hanr", "heg_jin", "heg_han", "heg_xia", "heg_shang", "heg_zhou", "heg_liang"} -- hanr 韩
local kingdomMapper = { ["ld__zhonghui"] = "heg_han", ["ld__simazhao"] = "heg_jin", ["ld__gongsunyuan"] = "heg_yan", ["ld__sunchen"] = "heg_chu" }
local function wildChooseKingdom(room, player, generalName)
  local choice
  local all_choices = table.clone(wildKingdoms)
  local choices = table.clone(all_choices)
  for _, p in ipairs(room.players) do
    table.removeOne(choices, p.role)
  end
  if player.general == generalName and kingdomMapper[generalName] and kingdomMapper[generalName] ~= player.role then -- 野心家钦定
    if table.contains(choices, kingdomMapper[generalName]) then
      choice = kingdomMapper[generalName]
    else
      choice = room:askForChoice(player, choices, "#heg_rule", "#wild-choose", false, all_choices)
    end
  else
    choice = room:askForChoice(player, choices, "#heg_rule", "#wild-choose", false, all_choices)
  end
  if choice then
    player.role = choice
    player.role_shown = true
    room:broadcastProperty(player, "role")
    room:sendLog{
      type = "#WildChooseKingdom",
      from = player.id,
      arg = choice,
      arg2 = "wild",
    }
  end
end  

local openheg_rule = fk.CreateTriggerSkill{
  name = "#openheg_rule",
  priority = 0.001,
  events = {fk.TurnStart, fk.GameOverJudge, fk.GameStart,fk.Deathed,fk.EventPhaseChanging},
  can_trigger = function(self, event, target, player, data)
    return target == player
  end,
  on_trigger = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      -- 鏖战
      if #room.alive_players < (#room.players > 6 and 5 or 4) and not room:getTag("BattleRoyalMode") then
        local ret = true
        for _, v in pairs(H.getKingdomPlayersNum(room)) do
          if v and v > 1 then
            ret = false
            break
          end
        end
        if ret then
          room:doBroadcastNotify("ShowToast", Fk:translate("#EnterBattleRoyalMode"))
          room:sendLog{
            type = "#EnterBattleRoyalModeLog",
          }
          room:setTag("BattleRoyalMode", true) 
          for _, p in ipairs(room.alive_players) do
            -- p:addFakeSkill("battle_royal&")
            -- p:addFakeSkill("battle_royal_prohibit&")
            room:handleAddLoseSkills(p, "battle_royal&", nil, false, true)
          end
        end
      end
      H.askForRevealGenerals(room, player, self.name, true, true, true, true, true) -- lord
    elseif event == fk.GameOverJudge then
      local winner = Fk.game_modes[room:getSettings('gameMode')]:getWinner(player)
      if winner ~= "" then
        for _, p in ipairs(room.alive_players) do
          if p.general == "anjiang" then p:revealGeneral(false) end
          if p.deputyGeneral == "anjiang" then p:revealGeneral(true) end
        end
        room:gameOver(winner)
        return true
      end
      room:setTag("SkipGameRule", true)
    elseif event == fk.Deathed then
      local damage = data.damage
      local body=room:getPlayerById(data.who)
      if damage and damage.from then
        local killer = damage.from
        if killer.kingdom ~= "unknown" and not killer.dead then
          if killer.kingdom == player.kingdom  then
            killer:throwAllCards("he")
          elseif  H.isSmallKingdomPlayer(killer) then
            killer:drawCards(3, "kill")
          else  H.isBigKingdomPlayer(killer)
            killer:drawCards(2, "kill")
          end
          if body.kingdom=="wild" then
            room:recover({
              who = killer,
              num = 1,
              recoverBy = killer,
              skillName = self.name,
            })
          end
        end
      end
      if string.find(player.general, "lord") then
        local players = table.map(table.filter(room.players, function(p) return
          (p:getMark("__heg_kingdom") == player.kingdom or (p.dead and p.kingdom == player.kingdom)) and p ~= player and p.kingdom ~= "wild"
        end), Util.IdMapper)
        room:sortPlayersByAction(players)
        for _, pid in ipairs(players) do
          local p = room:getPlayerById(pid)
          local oldKingdom = p.kingdom
          room:setPlayerMark(p, "__heg_kingdom", "wild")
          if oldKingdom ~= "unknown" then
            room:setPlayerProperty(p, "kingdom", "wild")
            if not p.dead then wildChooseKingdom(room, p, p.general) end
          end
        end
      end
    elseif event == fk.GameStart then
      local players=room.alive_players
      local chooselist={}
      for _, p in ipairs(players) do
        if p.role=="wild" then
          wildChooseKingdom(room, p, p.general)
        end
        if H.isSmallKingdomPlayer(p) then
          table.insertIfNeed(chooselist,p)
        end
      end
      huanhua_Newskill(room,chooselist)
    end
  end,
}
Fk:addSkill(openheg_rule)

openheg = fk.CreateGameMode{
  name = "open_heg_mode",
  minPlayer = 2,
  maxPlayer = 10,
  rule = openheg_rule,
  logic = openheg_getLogic,
  is_counted = function(self, room)
    return #room.players >= 6
  end,
  winner_getter = function(self, victim)
    local room = victim.room
    local alive = table.filter(room.alive_players, function(p)
      return not p.surrendered
    end)
    if #alive == 1 then
      local p = alive[1]
      return p.role
    end

    local winner -- = alive[1]
    for _, p in ipairs(alive) do
      if p.kingdom ~= "unknown" then
        winner = p
        break
      end
    end
    if not winner then return "" end
    local kingdom = H.getKingdom(winner)
    local i = H.getKingdomPlayersNum(room, true)[kingdom]
    for _, p in ipairs(alive) do
      if not H.compareExpectedKingdomWith(p, winner) then
        return ""
      end
      if p.kingdom == "unknown" then
        i = i + 1
      end
    end
    if i > #room.players // 2 and not H.getHegLord(room, winner) then return "" end
    return kingdom
  end,
  surrender_func = function(self, playedTime)
    local winner
    local kingdomCheck = true
    for _, p in ipairs(Fk:currentRoom().alive_players) do
      if p ~= Self then
        if not winner then
          winner = p
        elseif not H.compareKingdomWith(winner, p) then
          kingdomCheck = false
          break
        end
      end
    end
    return { { text = "heg: besieged on all sides", passed = kingdomCheck } }
  end,
}

Fk:loadTranslationTable{
  ["open_heg_mode"] = "明将国战",
  [":open_heg_mode"] = desc_openheg_mode,
  ["#openheg_rule"]="明将国战",
  ["openheg_choice"]="协站选择",
  ["#openheg-choice"]="选择技能",
}

return openheg
